package com.brother.rest;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.brother.Constants;
import com.brother.alarm.AlarmObserverImpl;
import com.brother.database.DataBase;
import com.brother.http.HttpSessionCopy;
import com.brother.model.AlarmType;
import com.brother.model.Customer;
import com.brother.model.RealTimeData;
import com.brother.model.Signal;
import com.brother.model.Tracker;
import com.brother.realtime.AlarmEmailSender;
import com.brother.realtime.ComandReader;
import com.brother.realtime.DataCommand;
import com.brother.realtime.MileageUpdator;
import com.brother.service.RealDataService;
import com.brother.service.TrackerService;
import com.brother.service.UserService;
import com.brother.util.CommonProperties;
import com.brother.util.LatLngConverter;

@RequestMapping("/restful")
@Controller
public class RESTController {
	
	
	private static Logger log = Logger.getLogger(RESTController.class);

	private static boolean isStarted = false;
	
    private static Map<String, Date> updateTime = new ConcurrentHashMap<String, Date>();
	
    public static void stopStatusUpdater(){
    	isStarted = false;
    }
    
	private static void startStatusUpdater(){
		isStarted = true;
		Thread t = new Thread(){
			public void run(){
				while(isStarted){
					long now = System.currentTimeMillis();
					List<String> removes = new ArrayList<String>();
					RealDataService rs = new RealDataService();
					try{
					for(String key : updateTime.keySet()){
						if(now - updateTime.get(key).getTime() > CommonProperties.getLostSignalTime())
						{
							rs.updateLastDataSignal(Signal.na, key);
						}
					}
					for(String s : removes){
						updateTime.remove(s);
					}
					}catch(Exception e){
						e.printStackTrace();
					}finally{
						DataBase.closeThreadConnection();
					}
					try {
						Thread.sleep(5000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		};
		t.start();
	}
	
    @SuppressWarnings("unchecked")
	@RequestMapping(value = "/login")
    public Map login(String username, String password, String locale){
    	log.debug("login, username="+username+", password="+password);
    	
    	Customer c = new Customer();
    	c.setName(username);
    	c.setPassword(password);
    	UserService srv = new UserService();
    	c = srv.login(c);
    	Map res = new HashMap();
    	if(c == null){
    		res.put("status", 1); //  登录失败
    	}else{
    		res.put("status", 0);
    		String key = UUID.randomUUID().toString().replaceAll("-", "");
    		res.put("loginKey", key);
    		RestSessionManager.getInstance().setAttribute(key, c);
    		c.setLocale(locale);
    		srv.setUserLocale(locale, c.getUserid()); 
    	}
    	DataBase.closeThreadConnection();
    	return res;
    }
    
    /**
     * @param imei
     * @param data date,time,lat,lot,speed,degrees
     * @return
     */
    @SuppressWarnings("unchecked")
	@RequestMapping(value = "/savedata")
    public Map savedata(String imei, String loginKey, String dataText){
    	Map res = new HashMap();
    	RealDataService rs = new RealDataService();
    	TrackerService tks = new TrackerService();
    	Customer user = (Customer) RestSessionManager.getInstance().getAttribute(loginKey);
    	if(user == null){
    		res.put("status", -1); // 没登陆
			return res;
    	}
    	log.debug("restful imei "+imei+","+dataText);
    	try{
    		List<Tracker> trackers = tks.findChildrenTracker(user.getUserid(), null, null, imei);
    		if(trackers.size() == 0){
				res.put("status", 1);
				return res;
			}
    		Tracker tracker = trackers.get(0);
			
			
	    	dataText = "A," + dataText + ",0";
	    	
			DataCommand cmd = null;
			try{
				cmd = ComandReader.parseSigleData(dataText.split(","));
			}catch(Exception e){
				log.error("the input data format is not correct: "+ dataText);
				res.put("status", 2);
				return res;
			}
			AlarmObserverImpl alo = new AlarmObserverImpl();
			final RealTimeData data = new RealTimeData();
			
			data.setOrient(cmd.getOrient());
			data.setAlarmObserver(alo);
			DecimalFormat nf1 =new DecimalFormat("00");
			data.setOrig_lat(nf1.format((int)Math.abs(cmd.getLat())) + Float.toString(Math.abs(LatLngConverter.toFen(cmd.getLat()))));
			data.setLatOrient(cmd.getLatOrient());
			data.setLat(cmd.getLat());
			DecimalFormat nf =new DecimalFormat("000");
			
			data.setOrig_lng(nf.format(Math.abs((int)Math.abs(cmd.getLng())))+Float.toString(Math.abs(LatLngConverter.toFen(cmd.getLng()))));
			data.setLng(cmd.getLng());
			data.setLngOrient(cmd.getLngOrient());
			
			data.setTrackerid(tracker.getTrackerid());
			data.setState(cmd.getFlag());
			data.setSignal(Signal.ok.name());
			data.setSpeed(cmd.getSpeed());
			
			data.setDistance("0");
			data.setTraceDateTime(cmd.getDate());
			data.setLanguage(user.getLocale());
			
			data.ckeckTriggerredAlarm();
			if(data.getState().equalsIgnoreCase(AlarmType.GPS_Pos.name())){
				data.setState(cmd.getFlag());
			}
			if(data.getState().equalsIgnoreCase(AlarmType.GPS_Pos.name())){
				data.setState("");
			}
			
			if(!data.getState().equals("") && !data.getState().equalsIgnoreCase(AlarmType.GPS_Pos.name())){
				if((!data.getState().equalsIgnoreCase(AlarmType.ACC_ON.name())) 
						&& (!data.getState().equalsIgnoreCase(AlarmType.DOOR_OPENED.name()))
						&& (!data.getState().equalsIgnoreCase(AlarmType.ACC_OFF.name()))
						&& (!data.getState().equalsIgnoreCase(AlarmType.DOOR_CLOSED.name()))){
					new Thread(){
						public void run(){
							try{
								AlarmEmailSender.sendMail(AlarmType.valueOf(data.getState()), data, "en");
							}catch(Exception e){
								log.error(e);
							}
						}
					}.start();
				}
			}
			
			if(cmd.getAccStat() != null){
				tks.updateAccStatus(tracker.getTrackerid(), ""+cmd.getAccStat());
			}
			if(cmd.getDoorStat() != null){
				tks.updateDoorStatus(tracker.getTrackerid(), ""+cmd.getDoorStat());
			}
			rs.insertData(data);
			
			if(tracker.getMileUpdate()==null || ((System.currentTimeMillis() - tracker.getMileUpdate().getTime())/1000
					> CommonProperties.getMileageUpdateTime())){ //  超过里程更新时间
				MileageUpdator.getInstance().addTask(tracker.getTrackerid());
			}
			updateTime.put(tracker.getTrackerid(), new Date());
			if(!isStarted){
				startStatusUpdater();
			}
    	}catch(Exception e){
    		log.error("saving data for rest", e);
    	}finally{
    		DataBase.closeThreadConnection();
    	}
    	res.put("status", 0);
    	return res;
    }
    
    
    
    
	
}
